fix: improve admin user search coverage#1466
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a correctness bug where admin user searches missed older users that fell outside the previous 500–5 000 user bounded scan window, replacing
Confidence Score: 4/5
|
There was a problem hiding this comment.
Pull request overview
This PR updates the admin user search behavior so that when a search query is provided it scans the full users dataset (rather than a bounded “recent users” window), while keeping the empty-query admin listing capped by limit. It also updates tests to prevent regressions where older matching users are missed.
Changes:
- Switch admin search path from bounded
take(...)scanning to full-tablecollect()scanning when a search query is present. - Keep empty-query listing behavior capped by
limit. - Update/add regression coverage to ensure older matching users are included in results.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| convex/users.ts | Changes admin list/search query behavior to collect() all users when searching. |
| convex/users.test.ts | Updates regression tests to assert full-list search behavior and preserve empty-query cap behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
convex/users.ts
Outdated
| } | ||
|
|
||
| const scannedUsers = await orderedUsers.take(computeUserSearchScanLimit(args.limit)); | ||
| const scannedUsers = await orderedUsers.collect(); |
There was a problem hiding this comment.
MAX_USER_SEARCH_SCAN/MIN_USER_SEARCH_SCAN are now unused after removing computeUserSearchScanLimit. With noUnusedLocals: true in tsconfig, this will fail TypeScript compilation; remove these constants or reintroduce usage (e.g., as a cap for the search scan).
| const scannedUsers = await orderedUsers.collect(); | |
| const scanLimit = clampInt(args.limit, MIN_USER_SEARCH_SCAN, MAX_USER_SEARCH_SCAN); | |
| const scannedUsers = await orderedUsers.take(scanLimit); |
| } | ||
|
|
||
| const scannedUsers = await orderedUsers.take(computeUserSearchScanLimit(args.limit)); | ||
| const scannedUsers = await orderedUsers.collect(); | ||
| const result = buildUserSearchResults(scannedUsers, normalizedSearch); |
There was a problem hiding this comment.
Calling orderedUsers.collect() for every non-empty search performs an unbounded full-table scan of the users table. This will scale linearly with user count and may hit Convex execution/response limits as the dataset grows; consider adding a bounded/paginated scan strategy or a dedicated search/index-based approach instead of collecting all users at once.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 146e2bb3b1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
convex/users.ts
Outdated
| } | ||
|
|
||
| const scannedUsers = await orderedUsers.take(computeUserSearchScanLimit(args.limit)); | ||
| const scannedUsers = await orderedUsers.collect(); |
There was a problem hiding this comment.
Restore bounded scan for admin user search
Changing queryUsersForAdminList from a bounded take(...) to collect() makes every non-empty admin search read the entire users table, which can hit Convex query limits (document/bytes read caps, including the 32K-doc ceiling) as the user base grows. In that state, searchInternal/list with a search term will error instead of returning matches, so this is a functional regression plus a significant bandwidth/cost increase.
Useful? React with 👍 / 👎.
8c56396 to
2034e55
Compare
|
Rebased onto current What’s on the branch now is the bounded-scan version plus exact handle / personal publisher lookup for older exact matches. It does not do an unbounded full-table collect on admin search. Local verification after rebase:
|
* build(deps-dev): bump vite in the npm_and_yarn group across 1 directory (#1561) Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). Updates `vite` from 8.0.1 to 8.0.5 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.5/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.5 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: detect generated-source template injection in skill scans (#1597) * fix: detect exposed resource identifiers in skill scans (#1598) * fix: restore ci checks after lockfile drift * refactor: address actionable review cleanup (#1601) * fix: prevent starring soft-deleted skills and fix star count reconciliation (#1605) * feat: Add support for Chinese Japanese and Korean(CJK) skills search (#1596) Merged via squash. Prepared head SHA: ab58f01 Co-authored-by: pq-dong <[email protected]> Co-authored-by: momothemage <[email protected]> Reviewed-by: @momothemage * docs: document CLI config paths across platforms (#1252) * docs: document CLI config paths across platforms * docs: clarify legacy config fallback --------- Co-authored-by: ImLukeF <[email protected]> * fix: point plugin metadata help link to OpenClaw docs (#1399) * fix: point plugin metadata help link to OpenClaw docs * fix: open plugin metadata docs in a new tab * fix(cli-auth): ensure fallback token renders before redirect on Windows/Chrome (#1486) * fix(cli-auth): ensure fallback token renders before redirect on Windows/Chrome React batches state updates, so setToken() and window.location.assign() previously raced: the navigation could fire before React re-rendered the fallback token UI. On Chrome/Windows this means a failed http:// redirect (ERR_CONNECTION_REFUSED, HTTPS-first interference) would replace the page with an error screen before the user ever saw the token. Use flushSync() to render the token synchronously, then attempt window.location.assign(). If the redirect fails the token and a "Retry redirect to CLI" link are already painted on screen. Fixes #1469 Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * test: cover cli auth fallback redirect --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]> Co-authored-by: ImLukeF <[email protected]> * fix: reduce souls browse overfetch (#1637) * fix: improve admin user search coverage (#1466) * fix admin user search coverage * fix admin user search without full table scan * feat: include stats in package detail API response Expose package detail stats through the shared API contract and the app client. This lands the original package detail stats work and folds in the follow-up cleanup to keep the response shape sourced from the shared schema instead of a hand-maintained app-local type. Co-authored-by: Saurabh Jain <[email protected]> * test: cover package detail stats response * fix: normalize misleading MIME types for text files * feat: modernize clawhub app store --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Luke <[email protected]> Co-authored-by: Momo <[email protected]> Co-authored-by: pqdong <[email protected]> Co-authored-by: Jholly <[email protected]> Co-authored-by: loong <[email protected]> Co-authored-by: Yaovi <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Co-authored-by: Saurabh Jain <[email protected]>
Summary
Admin user search was only scanning a recent slice of users when a query was present. That meant an older existing account could be missing from the admin Users page even when the search text matched exactly.
This PR changes searched admin listings to scan the full ordered user set, while keeping the default non-search listing capped by
limit. It also adds a regression test covering an older matching user outside the previous recent scan window.Testing
Not run locally in this environment because
bunis unavailable.